package com.web.controller.web;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.Page;
import com.web.controller.web.WebSysLogController.DetailsColumns;
import com.web.controller.web.WebSysLogController.OrderLogColumns;
import com.web.dao.AccountMapper;
import com.web.dao.CompanyBonusDetailMapper;
import com.web.dao.CompanyReportMapper;
import com.web.dao.MemberMapper;
import com.web.dao.MerchantDetailMapper;
import com.web.dao.MessageMapper;
import com.web.dao.OrderRecordForPlatformMapper;
import com.web.dao.PlatformMapper;
import com.web.dao.ProfitDetailMapper;
import com.web.domain.WebResponse;
import com.web.dto.AllotBonusDto;
import com.web.entity.Account;
import com.web.entity.CompanyBonusDetail;
import com.web.entity.CompanyReport;
import com.web.entity.Member;
import com.web.entity.MerchantDetail;
import com.web.entity.Message;
import com.web.entity.OrderRecordForPlatform;
import com.web.entity.Platform;
import com.web.entity.ProfitDetail;
import com.web.manager.jpush.SendJPushMessage;

@Controller
@Transactional
public class AllotBonusController {
	@Autowired
	private AccountMapper accountMapper;
	@Autowired
	private MemberMapper memberMapper;
	@Autowired
	private ProfitDetailMapper profitDetailMapper;
	@Autowired
	private MerchantDetailMapper merchantDetailMapper;
	@Autowired
	private CompanyBonusDetailMapper companyBonusDetailMapper;
	@Autowired
	private CompanyReportMapper companyReportMapper;
	@Autowired
	private PlatformMapper platformMapper;
	@Autowired
	private MessageMapper messageMapper;
	@Autowired
	private OrderRecordForPlatformMapper orderRecordForPlatformMapper;

	// 页面显示
    @RequestMapping(value = "sysf/allotBonus", method = RequestMethod.GET)
    public String allotBonus(Model modle, HttpServletRequest request) {
    	return "allotBonus";
    }
    
    // 取得订单信息
    @RequestMapping("getOrderInfo")
    @ResponseBody
    public WebResponse getOrderInfo(String orderNum) {
		if (isEmpty(orderNum)) {
			return WebResponse.fail("订单号不能为空，请核对！");
		}

		// 获取订单是否存在
		OrderLogColumns orderColumns = new OrderLogColumns();
		orderColumns.setOrderNum(orderNum);
		Page<OrderRecordForPlatform> OrderRecordForPlatforms = orderRecordForPlatformMapper.selectAllOrderLogs(orderColumns);
		if (null == OrderRecordForPlatforms || 0 == OrderRecordForPlatforms.size()) {
			return WebResponse.fail("不存在该订单号，请核对！");
		}

		// 订单信息
		OrderRecordForPlatform orderRecord = OrderRecordForPlatforms.get(0);
		WebResponse<OrderRecordForPlatform> res = new WebResponse<OrderRecordForPlatform>();
		res.addData(orderRecord);
		return res;
    }
    
    // 根据电话号码获取人员姓名
    @RequestMapping("getUserName")
    @ResponseBody
    public WebResponse getUserName(String phone) {
    	Member member = memberMapper.selectByMobile(phone);
		if (null == member) {
			return WebResponse.fail("不存在用户" + phone + "，请核对！");
		}
		WebResponse<String> res = new WebResponse<String>();
		return res.addData(member.getName());
    }

    // 分配奖金
	@RequestMapping("allotBonus")
	@ResponseBody
	public WebResponse allotBonus(AllotBonusDto allotBonus) {
		String orderNum = allotBonus.getOrderNum();
		if (isEmpty(orderNum)) {
			return WebResponse.fail("订单号不能为空，请核对！");
		}

		// 获取订单是否存在
		OrderLogColumns orderColumns = new OrderLogColumns();
		orderColumns.setOrderNum(orderNum);
		Page<OrderRecordForPlatform> OrderRecordForPlatforms = orderRecordForPlatformMapper.selectAllOrderLogs(orderColumns);
		if (null == OrderRecordForPlatforms || 0 == OrderRecordForPlatforms.size()) {
			return WebResponse.fail("不存在该订单号，请核对！");
		}

		// 订单信息
		OrderRecordForPlatform orderRecord = OrderRecordForPlatforms.get(0);

		Map<String, BigDecimal> bonusMap = new HashMap<String, BigDecimal>();
		// 分配总金额
		BigDecimal total = new BigDecimal("0.00");

		// 分配人员不为空且分配金额大于0时做分配操作
		if (false == isEmpty(allotBonus.getShareholder().trim()) && null != allotBonus.getShareholderMoney()) {
			if (allotBonus.getShareholderMoney().compareTo(new BigDecimal("0")) > 0) {
				bonusMap.put(allotBonus.getShareholder().trim().substring(0, 11), allotBonus.getShareholderMoney());
				total = total.add(allotBonus.getShareholderMoney());
			}
		}

		// 分配人员不为空且分配金额大于0时做分配操作
		if (false == isEmpty(allotBonus.getSeniorPartner().trim()) && null != allotBonus.getSeniorPartnerMoney()) {
			if (bonusMap.containsKey(allotBonus.getSeniorPartner().trim().substring(0, 11))) {
				return WebResponse.fail("已存在人员" + allotBonus.getSeniorPartner().trim() + "，请核对！");
			}
			if (allotBonus.getSeniorPartnerMoney().compareTo(new BigDecimal("0")) > 0) {
				bonusMap.put(allotBonus.getSeniorPartner().trim().substring(0, 11), allotBonus.getSeniorPartnerMoney());
				total = total.add(allotBonus.getSeniorPartnerMoney());
			}
		}

		// 分配人员不为空且分配金额大于0时做分配操作
		if (false == isEmpty(allotBonus.getCityPartner().trim()) && null != allotBonus.getCityPartnerMoney()) {
			if (bonusMap.containsKey(allotBonus.getCityPartner().trim().substring(0, 11))) {
				return WebResponse.fail("已存在人员" + allotBonus.getCityPartner().trim() + "，请核对！");
			}
			if (allotBonus.getCityPartnerMoney().compareTo(new BigDecimal("0")) > 0) {
				bonusMap.put(allotBonus.getCityPartner().trim().substring(0, 11), allotBonus.getCityPartnerMoney());
				total = total.add(allotBonus.getCityPartnerMoney());
			}
		}

		// 分配人员不为空且分配金额大于0时做分配操作
		if (false == isEmpty(allotBonus.getAgency().trim()) && null != allotBonus.getAgencyMoney()) {
			if (bonusMap.containsKey(allotBonus.getAgency().trim().substring(0, 11))) {
				return WebResponse.fail("已存在人员" + allotBonus.getAgency().trim() + "，请核对！");
			}
			if (allotBonus.getAgencyMoney().compareTo(new BigDecimal("0")) > 0) {
				bonusMap.put(allotBonus.getAgency().trim().substring(0, 11), allotBonus.getAgencyMoney());
				total = total.add(allotBonus.getAgencyMoney());
			}
		}

		// 分配总金额小于等于0
		if (1 != total.compareTo(new BigDecimal("0"))) {
			return WebResponse.fail("分配总金额必须大于0，请核对！");
		}

		Map<Member, BigDecimal> memberMap = new HashMap<Member, BigDecimal>();
		for (String phone : bonusMap.keySet()) {
			Member member = memberMapper.selectByMobile(phone);
			if (null == member) {
				return WebResponse.fail("不存在分配用户" + phone + "，请核对！");
			}

			memberMap.put(member, bonusMap.get(phone));
		}

		// 分配总奖金不能大于该笔订单的商家货款收入
		if (1 == total.compareTo(orderRecord.getMerchantIncome())) {
			return WebResponse.fail("分配总奖金已大于该笔订单中商家收入的货款，请核对分配金额！");
		}

		Date date = new Date();
		// 记录所有分配人员姓名电话及分配金额
		StringBuilder bonusInfo = new StringBuilder();
		// 记录分配奖金明细
		StringBuilder bonusDetail = new StringBuilder();
		// 个人账户中商户货款 - 分配总奖金
		// 个人商户货款明细 - 分配总奖金
		// 各分配人奖金增加
		String result = allocation(orderNum, total, memberMap, bonusInfo, bonusDetail, date);
		
		// 未成功操作完成
		if (!isEmpty(result)) {
			return WebResponse.fail(result);
		}

		// 公司平台奖金池增加
		platformMapper.bonusPoolAdd(total, (long) 1);

		// 公司奖金池记录描述
		StringBuilder description = new StringBuilder("订单");
		description.append(orderNum);
		description.append("交易，秒商奖金分配，");
		description.append(bonusInfo.substring(0, bonusInfo.length() - 1) + "。");
		// 公司奖金池
		CompanyBonusDetail companyBonusDetail = new CompanyBonusDetail();
		companyBonusDetail.setContent("订单" + orderNum + "秒商奖金分配");
		companyBonusDetail.setDetail("+" + total);
		companyBonusDetail.setFromNum(orderNum);
		companyBonusDetail.setName(orderRecord.getConsumer());
		companyBonusDetail.setPhone(orderRecord.getConsumerPhone());
		companyBonusDetail.setBal(platformMapper.selectByPrimaryKey((long) 1).getBonusPool().toString());
		companyBonusDetail.setDescription(description.toString());
		companyBonusDetail.setCreateTime(date);
		companyBonusDetail.setModifyTime(date);
		companyBonusDetailMapper.insert(companyBonusDetail);

		bonusDetail.append("\r\n=" + platformMapper.selectByPrimaryKey((long) 1).getBonusPool().toString());

		// 公司奖金汇总表记录增加
		CompanyReport companyReport = new CompanyReport();
		companyReport.setAdd("0");
		companyReport.setReduce("0");
		companyReport.setProfitBal(bonusDetail.toString());
		companyReport.setUnWithdraw("-" + total + "\r\n=" + accountMapper.countMerchantNum().toString());
		companyReport.setTotal("+0\r\n=" + getTotalFund());
		companyReport.setReserve1("秒商奖金分配");
		companyReport.setCreateTime(date);
		companyReport.setModifyTime(date);
		companyReportMapper.insert(companyReport);

		return WebResponse.ok("分配成功！");
	}
	
	/**
	 * 配置各账户金额变动 (个人账户中商户货款 - 分配总奖金、个人商户货款明细 - 分配总奖金 、各分配人奖金增加)
	 * @param orderNum 订单号
	 * @param total 分配总金额
	 * @param memberMap 各分配人信息
	 * @param bonusInfo 记录所有分配人员姓名电话及分配金额
	 * @param bonusDetail 记录分配奖金明细
	 * @param date 操作发生时间
	 * @return 返回分配操作结果
	 */
	private String allocation(String orderNum, BigDecimal total, Map<Member, BigDecimal> memberMap,
			StringBuilder bonusInfo, StringBuilder bonusDetail, Date date) {
		DetailsColumns detailsColumns = new DetailsColumns();
		detailsColumns.setFromNum(orderNum);
		Page<MerchantDetail> merchantDetails = merchantDetailMapper.selectAllMerchantLogs(detailsColumns);
		if (null == merchantDetails || 0 == merchantDetails.size()) {
			return "订单有误，请核对！";
		}

		// 获取个人商户货款信息
		MerchantDetail merchantDetail = new MerchantDetail();
		Boolean existIncome = false;
		
		for (MerchantDetail md : merchantDetails) {
			// 商户货款类型是收入
			if (1 == md.getType()) {
				merchantDetail = md;
				existIncome = true;
				break;
			}
		}
		
		// 商户货款明细中没有该笔订单的收入
		if (false == existIncome) {
			return "商户货款明细中没有该笔订单的收入，请确认！";
		}

		// 判断账户中商户货款余额是否够分配总奖金
		Account merchantAccount = accountMapper.selectByPrimaryKey(merchantDetail.getaId());
		if (null == merchantAccount) {
			return "不存在商户账户" + merchantDetail.getPhone() + "，请核对！";
		} else if (1 == total.compareTo(merchantAccount.getMerchantPayment())) {
			return "分配总奖金已大于该用户账户中商家货款余额，无法进行分配金额！";
		}

		// 商户货款金额 - 分配奖金总额
		accountMapper.merchantPaymentSubtract(total, merchantDetail.getaId());

		// 个人商户货款明细 记录
		merchantDetail.setContent("支出(秒商奖金)");
		merchantDetail.setDetail("-" + total);
		merchantDetail.setBal(accountMapper.selectByPrimaryKey(merchantAccount.getId()).getMerchantPayment().toString());
		merchantDetail.setCreateTime(date);
		merchantDetail.setModifyTime(date);
		merchantDetail.setType(5);
		merchantDetail.setTotalBal(accountMapper.countMerchantNum().toString());
		merchantDetailMapper.insert(merchantDetail);

		// 各分配人奖金增加
		for (Member member : memberMap.keySet()) {
			Account account = accountMapper.selectByMid(member.getId());
			if (null == account) {
				return "不存在分配的用户账户" + member.getPhone() + "，请核对！";
			}

			// 分配奖金金额
			BigDecimal bonus = new BigDecimal("0.00");
			bonus = bonus.add(memberMap.get(member));

			// 分配人账户奖金变更
			accountMapper.profitAdd(bonus, account.getId());
			// 该分配人奖金增加后金额
			account.setProfit(account.getProfit().add(bonus));

			// 分配人累计奖金变更
			member.setBonusAmt(member.getBonusAmt().add(bonus));
			memberMapper.updateByPrimaryKeySelective(member);

			// 分配人分润账户增加记录
			ProfitDetail profitDetail = new ProfitDetail();
			profitDetail.setaId(account.getId());
			profitDetail.setContent("秒商奖金");
			profitDetail.setDetail("+" + bonus.toString());
			profitDetail.setName(member.getName());
			profitDetail.setPhone(member.getPhone());
			profitDetail.setFromNum(orderNum);
			profitDetail.setBal(account.getProfit().toString());
			profitDetail.setCreateTime(date);
			profitDetail.setModifyTime(date);
			profitDetailMapper.insert(profitDetail);

			bonusInfo.append(member.getName());
			bonusInfo.append("[" + member.getPhone() + "]获得");
			bonusInfo.append(bonus + "元；");

			bonusDetail.append("+" + bonus);

			// 消息记录增加
			Message message = new Message();
			message.setTarget(member.getId());
			message.setTargetName(member.getName());
			message.setTitle("秒商奖金");
			message.setContent("恭喜！您获得了一份秒商奖金，请注意查收。");
			message.setFrom((long) 0);
			message.setFromName("系统");
			message.setCreateTime(date);
			message.setModifyTime(date);
			messageMapper.insertSelective(message);
			// 个推信息推送
			SendJPushMessage.jPushByMessage(message);
		}
		return "";
	}

	/**
	 * 获取公司账户资金总额
	 */
	private String getTotalFund() {
		BigDecimal totalFund = new BigDecimal("0.00");
		// 公司平台资金
		Platform platform = platformMapper.selectByPrimaryKey((long) 1);

		// 现存商户货款总额
		BigDecimal merchantNum = accountMapper.countMerchantNum();
		// 公司利润总额
		BigDecimal profit = platform.getCompanyProfitPool();
		// 公司资金总额
		BigDecimal companyFund = platform.getCompanyFundPool();
		// 市场资金总额
		BigDecimal marketFund = platform.getMarketFundPool();
		// 奖金总额
		BigDecimal bonus = accountMapper.countProfitNum();
		// 手续费总额
		BigDecimal poundage = platform.getPoundagePool();
		// 睿积分总额
		BigDecimal coreNum = accountMapper.countCoreNum();
		// 消费账户总额
		BigDecimal consumeNum = accountMapper.countConsumeNum();

		totalFund = totalFund.add(merchantNum);// 现存商户货款总额
		totalFund = totalFund.add(profit);// 公司利润总额
		totalFund = totalFund.add(companyFund);// 公司资金总额
		totalFund = totalFund.add(marketFund);// 市场资金总额
		totalFund = totalFund.add(bonus);// 奖金总额
		totalFund = totalFund.add(poundage);// 手续费总额
		totalFund = totalFund.add(coreNum);// 睿积分总额
		totalFund = totalFund.add(consumeNum);// 消费账户总额

		return totalFund.toString();
	}
	
	/**
	 * null或空字符串都等于false
	 */
    private static boolean isEmpty(String cs) {
        return cs == null || cs.length() == 0;
    }
}
